// 接口: 抽象类 (有抽象的也有非抽象的)  接口必须是抽象的(没有具体的实现)

// 接口的概念:类型检查 就是描述数据类型的结构、或者形状的，定义好结构，在去针对结构来进行实现

// type 和 interface 的区别
// 一般情况下 描述对象,类 我们采用interface更多一些, interface无法声明联合类型
// type 可以快速声明类型 联合类型
//  能用type就用type 不用interface (复杂用type,简单的用interface),interface 可以重名，type 不可以

// interface a{}
// interface a{}

// type a = ''
// type a = ''

interface IPerson {
    username:string
}

let person: IPerson = {
    username:'abc'
}

// 接口可以描述函数
interface ICounter {
    (): number
    count:number
}

const counter:ICounter = ()=>{
    return counter.count++
}
counter.count = 0

// 3表示接口的属性 可有可无
interface IVeg {
    readonly name: string
    taste: string
    size: number
    color?: string 
}
interface IVeg { // 同名的合并

}
const veg:IVeg = {
    name:'西红柿',
    taste: '西红柿',
    size: 50,
    color:'红色'
}

// 断言 as用的多

interface IArray {
    [key: number]:any
}

let arr4:IArray = { 0:1,1:2,2:'abc',3:true }

// 接口套接口
interface ResponseData {
    username: string,
    token: string
}

interface ReturnVal {
    code: number,
    data: ResponseData
}

// 通过索引访问来获取内部类型
type ICode = ReturnVal['code']
type IUsername = ReturnVal['data']['username']

function printLabel(labelledObj: { label: string }) {
    console.log(labelledObj.label);
}

let myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

interface LabelledValue {
    label: string
}

function printLabel2(labelledObj: LabelledValue){
    console.log(labelledObj.label)
}
let myObj2 = { size: 10, label: "Size 10 Object"}
printLabel2(myObj2);

// 接口选链属性
interface SquareConfig {
    color?: string;
    width?: number;
}

function createSquare(config: SquareConfig) {
let newSquare = { color: "white", area: 100 };
if (config.color) {
    newSquare.color = config.color;
}
if (config.width) {
    newSquare.area = config.width * config.width;
}
return newSquare;
}

let mySquare = createSquare({color: "black",width:20});

console.log('mySquare',mySquare)

// 接口只读属性

interface Point2 {
    readonly x: number;
    readonly y: number;
}

let p1: Point2 = { x: 10, y:20}
// p1.x = 5

// 批量只读

let a:number[]= [1,2,3,4]
let ro:ReadonlyArray<number> = a
// ro[0] = 12
// ro.push(5)

export {}